/**
 * cs340 Fatboy Mafia Team 
 */

package fatboy.communication;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 *	@author Ilya Vinogradov
 *  @date 27-Jan-10 14:17 PM
 * 
 *	SingleServer is a single-threaded version of the communication server for
 *	 the hyper web. As of now it is designed to run forever.  
 */
public class SingleServer {
	
	/** Stores the socket object */
	private static Socket socket = null;
	
	/** Indicates whether to accept more connections or not */
	private static boolean communicating = true;
	
	/** Counter of the accepted connections 
	 * (and, thus, commands received and executed).
	 */
	private static int commandCount = 0;
	
	/** Communication Port Number (4444 by default) */
	private static int port;

	
	/**
	 * You can not instantiate SingleServer. You can just run it.
	 * @param args - command line arguments (ignored)
	 * @throws IOException when there are problems connecting
	 */
	public static void main(String[] args) throws IOException {

		ServerSocket serverSocket = null;
		port = PortNumber.getRuntimePort().getPort();
		
		try {
			serverSocket = new ServerSocket(port);
			System.out.println("Listening for connections on port " + port);
		} catch (IOException e) {
			System.err.println("Could not listen on port: " + port);
			System.exit(1);
		}

		//this loop accepts new connection, every time  the old session is terminated
		while (true) {
					
			Socket clientSocket = null;
			
			//tries to accept the connection from the client
			try {
				clientSocket = serverSocket.accept();
				communicating = true;
			} catch (IOException e) {
				System.err.println("Accept failed.");
				communicating = false;
				// System.exit(1);
			}

			//if connection is accepted - process it until it's terminated
			if (communicating) {
				
				socket = clientSocket;
				
				try {
					// open the output stream through the socket (for response)
					ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());

					// open the output stream through the socket (for response)
					ObjectInputStream in = new ObjectInputStream(socket
							.getInputStream());

					// Address the needs of the client
					Command command = (Command) in.readObject();
					System.out.println("\n------------------- INCOMMING TRANSMISSION "
									+ (++commandCount) + " ------------------");
					
					System.out.println("\tReceived a command from the client: \""
							+ command.toString() + "\"");

					Object returnValue = command.excecute();
					System.out.println("\tExecuted command returned: \""
							+ returnValue + "\"");

					if (returnValue != null) {
						System.out.println("\tSending the result back to the client...");
						out.reset();
						out.writeObject(returnValue);
						out.flush();
					}

					// communicating = true;

					// Assistance is no longer needed
					// if (!communicating)
					// break;
					// }

					
					clientSocket.close();

				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (ClassNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		// serverSocket.close();   //to reach this code, client must send something
								   //so the server can terminate the outer while loop
	}
}
